﻿using Elasticsearch.Synchronize.Domain.Events;
using Elasticsearch.Synchronize.Domain.SeedWork;
using MediatR;
using MongoDB.Bson;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Elasticsearch.Synchronize.Domain.Aggregates.SynchronizeAggregate
{
    public class SynchronizeRule : Entity, IAggregateRoot
    {
        public SynchronizeRule(IMediator mediator = null) : base(mediator)
        {
            this.RuleProjection = new List<string>();
            this.RuleDataList = new List<BsonDocument>();
            this.RuleItemList = new List<SynchronizeItem>();
            this.RuleItemFilterList = new List<string>();
        }

        public string Identity { get; set; }

        public string RuleMongoServerUrl { get; set; }

        public string RuleMongoDatabase { get; set; }

        public string RuleMongoCollection { get; set; }

        public string RuleFilter { get; set; }

        public List<string> RuleProjection { get; set; }

        public List<BsonDocument> RuleDataList { get; set; }

        public BsonDocument CurrentRuleDataItem { get; set; }

        public string CurrentRuleItemFilter { get; set; }

        public List<SynchronizeItem> RuleItemList { get; set; }

        public List<string> RuleItemFilterList { get; set; }

        public string RuleItemMongoServerUrl { get; set; }

        public string RuleItemMongoDatabase { get; set; }

        public string RuleItemMongoCollection { get; set; }

        public string RuleItemFilterTemplate { get; set; }

        public string RuleItemElasticsearchServerUrl { get; set; }

        public string RuleItemElasticsearchIndexName { get; set; }

        public string RuleItemElasticsearchTypeName { get; set; }

        public bool Enabled { get; set; }

        public override bool IsTransient()
        {
            throw new NotImplementedException();
        }

        public SynchronizeRule Merge(SynchronizeRule rule)
        {
            this.Identity = rule.Identity;
            this.RuleMongoServerUrl = rule.RuleMongoServerUrl;
            this.RuleMongoDatabase = rule.RuleMongoDatabase;
            this.RuleMongoCollection = rule.RuleMongoCollection;
            this.RuleFilter = rule.RuleFilter;
            this.RuleProjection = rule.RuleProjection;
            this.RuleDataList = rule.RuleDataList;
            this.CurrentRuleDataItem = rule.CurrentRuleDataItem;
            this.CurrentRuleItemFilter = rule.CurrentRuleItemFilter;
            this.RuleItemList = rule.RuleItemList;
            this.RuleItemFilterList = rule.RuleItemFilterList;
            this.RuleItemMongoServerUrl = rule.RuleItemMongoServerUrl;
            this.RuleItemMongoDatabase = rule.RuleItemMongoDatabase;
            this.RuleItemMongoCollection = rule.RuleItemMongoCollection;
            this.RuleItemFilterTemplate = rule.RuleItemFilterTemplate;
            this.RuleItemElasticsearchServerUrl = rule.RuleItemElasticsearchServerUrl;
            this.RuleItemElasticsearchIndexName = rule.RuleItemElasticsearchIndexName;
            this.RuleItemElasticsearchTypeName = rule.RuleItemElasticsearchTypeName;
            this.Enabled = rule.Enabled;

            return this;
        }

        public void Enable()
        {
            base.DomainEventPublish(null);
        }

        public void Disable()
        {
            base.DomainEventPublish(null);
        }

        public void Scan()
        {
            base.DomainEventPublish(new ScanSynchronizeRuleDomainEvent(this, DateTime.Now));
        }

        public void GetRuleData()
        {
            base.DomainEventPublish(new GetRuleDataDomainEvent(this, DateTime.Now));
        }

        public void TraverseRuleData()
        {
            base.DomainEventPublish(new TraverseRuleDataDomainEvent(this, DateTime.Now));
        }

        public void AddItem()
        {
            base.DomainEventPublish(new AddRuleItemDomainEvent(this, DateTime.Now));
        }

        public void RemoveItem(SynchronizeItem item)
        {
            base.DomainEventPublish(new RemoveRuleItemDomainEvent(this, item, DateTime.Now));
        }
    }
}